﻿using ManagementTools.Models;
using ManagementTools.Service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ManagementTools
{
    public partial class FrmPostCodeGenerate : Form
    {
        Assembly mAssembly ;
        string mHisFile = "postCodeGen.his";
        string mAssemblyFile;

        public FrmPostCodeGenerate()
        {
            InitializeComponent();
        }

        private void FrmPostCodeGenerate_Load(object sender, EventArgs e)
        {
            StringBuilder sb= new StringBuilder();
            sb.AppendLine(" **** 使用说明 ****  ");
            sb.AppendLine("本功能对由代码生成器生成的前后端代码进行改造，以提供父子类关联查询修改功能");
            sb.AppendLine("几点注意事项：");
            sb.AppendLine("1.子类需存在一个外键指向父类的ID，命名为'{父类名}Id'");
            sb.AppendLine("2.在代码生成器中指定外键，并指定'显示字段'");
            sb.AppendLine("3.输出时，子类的的vue文件放在父类名\\子类名下"); 
            txtEcho.Text = sb.ToString();
            if (File.Exists(mHisFile))
            {
                var his = FrmPostCodeGenerateViewModel.LoadFromJsonFile(mHisFile);
                if(!string.IsNullOrEmpty(his.AssemblyFile))
                {
                    mAssemblyFile=his.AssemblyFile;
                    mAssembly = Assembly.LoadFrom(his.AssemblyFile);
                    cbSon.DataSource = mAssembly.GetTypes().Where(it => it.Namespace.EndsWith("Entity")).Select(en => en.Name).ToList();
                    cbSon.SelectedItem = his.SonTypeName;
                    cbParent.SelectedItem = his.ParentTypeName;
                    cbFkName.SelectedItem = his.FkColumnName;
                }
               
                txtSrcMainDir.Text = his.SrcMainDir;
                txtTargMainDir.Text = his.DstMainDir;

            }
        }

        private void btnLoadAssembly_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog()
            {
                Filter = "动态链接库(*.DLL)|*.DLL|全部文件(*.*)|*.*",
                RestoreDirectory = true,
                InitialDirectory = Environment.CurrentDirectory,
                FileName = "Magic.Application.dll"
            };
            if (fd.ShowDialog() == DialogResult.OK)
            {
                mAssembly = Assembly.LoadFrom(fd.FileName);
                mAssemblyFile = fd.FileName;
                var list= mAssembly.GetTypes().Where(it => it.Namespace.EndsWith("Entity")).Select(en=>en.Name).ToList();
                //cbParent.DataSource = list;
                cbSon.DataSource = list;


            }
        }

        private void cbParent_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbParent.SelectedIndex < 0) return;
            var type = mAssembly.GetTypes().FirstOrDefault(t=>t.Name==cbParent.Text);
            if(type != null)
                cbFkName.DataSource = type.GetProperties().Select(p=>p.Name).ToList();
            else
                cbFkName.DataSource=null;
        }

        private void cbSon_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(cbSon.SelectedIndex<0) return;
            var list = mAssembly.GetTypes().Where(it =>it.Name!=cbSon.Text && it.Namespace.EndsWith("Entity")).Select(en => en.Name).ToList();
            cbParent.DataSource = list;
        }

        private async void btnGo_Click(object sender, EventArgs e)
        {
            if(cbFkName.SelectedIndex<0) return;    
            if(cbParent.SelectedIndex<0) return;
            if (cbSon.SelectedIndex < 0) return;
            if(string.IsNullOrEmpty(txtSrcMainDir.Text)) return;
            if(string.IsNullOrEmpty(txtTargMainDir.Text)) return;
            FrmPostCodeGenerateViewModel model = new FrmPostCodeGenerateViewModel
            {
                AssemblyFile = mAssemblyFile,
                DstMainDir = txtTargMainDir.Text,
                SrcMainDir = txtSrcMainDir.Text,
                SonTypeName = cbSon.Text,
                ParentTypeName = cbParent.Text,
                FkColumnName = cbFkName.Text,
            };
            model.SaveToJsonFile(mHisFile);
            var parent = mAssembly.GetTypes().FirstOrDefault(t => t.Name == cbParent.Text);
            var son = mAssembly.GetTypes().FirstOrDefault(t => t.Name == cbSon.Text);
            if(parent != null&&son!=null)
            {
                PatchForParentSonService service = new PatchForParentSonService(parent, son, txtSrcMainDir.Text, txtTargMainDir.Text, cbFkName.Text);
                var ans = service.PatchForOneToMulti();
                if (ans)
                {
                    MessageBox.Show("请将补丁完成后的文件拷贝到相应目录", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show(service.ErrMsg, "有错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show($"指定的assembly不含{cbParent.Text}或{cbSon.Text}","错误",MessageBoxButtons.OK,MessageBoxIcon.Error);
            }
        }

        private void txtSrcMainDir_DoubleClick(object sender, EventArgs e)
        {
            FolderBrowserDialog fb = new FolderBrowserDialog()
            {
                Description = "指定代码生成的源代码目录",

            };
            if (fb.ShowDialog() == DialogResult.OK) txtSrcMainDir.Text = fb.SelectedPath;
        }

        private void txtTargMainDir_DoubleClick(object sender, EventArgs e)
        {
            FolderBrowserDialog fb = new FolderBrowserDialog()
            {
                Description = "指定代码生成的源代码目录",
                ShowNewFolderButton = true,
            };
            if (fb.ShowDialog() == DialogResult.OK) txtTargMainDir.Text = fb.SelectedPath;
        }
    }
}
